 /*
  * Copyright (c) 2015 sb Jung.
  * All right reserved.
  */
package kr.co.j2b.common;

import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StopWatch;

/**
 * <pre>
 * kr.co.j2b.common 
 *    |_ RequestResponseLogAdvice.java
 * </pre>
 * @date : 2015. 4. 7. 오후 3:10:28
 * @author : J-PC
 */
public class RequestResponseLogAdvice {
	
	/** 
	 * LOG4J 설정을 위한 Log 객체 
	 */
	protected static final Log logger = LogFactory.getLog("RR_LOG");
	
	private static String localHostName;
	
	static  {
		try {
			// Local Server 의 HostName 및 HostAddress
			java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
			localHostName = localMachine.getHostName();
			//localHostAddress = localMachine.getHostAddress();
		} catch (UnknownHostException uhe) {
			logger.error("Cannot obtain local host name", uhe);
		}
	}
	
	public RequestResponseLogAdvice(){}
	
	@Value("#{file['service.name']}")
	private static String SERVICE_NAME;
	//private static final String DIRECTION_TYPE_REQUEST = "REQ";
	//private static final String DIRECTION_TYPE_RESPONSE = "REP";
	private static final String RESULT_TYPE_SUCCESS = "SUCC";
	private static final String RESULT_TYPE_FAIL = "FAIL";
	
	public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
		
		Map<String, Object> resultMap 	= new HashMap<String, Object>(); // 실행 전 입력 정보
		
		long startTime = System.currentTimeMillis(); 	// 시작 시간
		String startTimeStr = ""; 						// 시작시간
		StopWatch stopWatch = new StopWatch();  		// 응답 시간 측정
		Signature signature = joinPoint.getSignature();	// 메소드명
		String targetClassName = joinPoint.getTarget().getClass().getName(); // Class Name
		Object returnValue = null;
		
		try{
			
			SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMddHHmmss");
			startTimeStr = ymd.format(new Date(startTime));
			
			if (true){
				returnValue = joinPoint.proceed(); // Service 정상 처리
				
				resultMap.put("serviceName", SERVICE_NAME);
				resultMap.put("startTimeStr", startTimeStr);
				resultMap.put("hostName", localHostName);
				resultMap.put("className", targetClassName);
				resultMap.put("signature", signature);
				
				if(stopWatch.isRunning()){
					stopWatch.stop();	 // 응답시간 종료
				}
				
				logger.info(getLogMake(resultMap, true));
			}			
		}catch(Exception e){
			
		}
		
		return returnValue;
	}
	
	/**
	 * 
	 * @param resultMap
	 * @return
	 */
	public String getLogMake(Map<String, Object> resultMap, boolean state){
		StringBuffer logbuf = new StringBuffer();
		
		if ( state ){
			logbuf.append(RESULT_TYPE_SUCCESS);
		}else{
			logbuf.append(RESULT_TYPE_FAIL);
		}	
		
		logbuf.append(",")
		      .append(SERVICE_NAME)
		      .append(",")
		      .append(resultMap.get("hostName"))
		      .append(",")
		      .append(resultMap.get("className"))
		      .append(",")
		      .append(resultMap.get("signature"));
		
		return logbuf.toString();
	}

}
